package com.uuah.server.component.model.resolvers;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.uuah.exception.UuahException;
import com.uuah.server.api.IUuahEventContext;
import com.uuah.server.api.component.model.IEntryPointResolver;
import com.uuah.server.api.component.model.IEntryPointResolverSet;
import com.uuah.server.component.model.InvocationResult;
import com.uuah.utils.CollectionUtils;

/**
 * Provides the default implementation of an
 * {@link com.uuah.server.api.component.model.IEntryPointResolverSet} It
 * resolves a method to call on the given service when an event is received.
 * This object maintains a set of Resolvers that will be used in order to
 * resolve an entrypoint on a service object until one is found or until the set
 * is exhausted.
 *
 * <p>
 * update record:updator，update time，update content and version
 * </p>
 *
 * @author <a href="jonny_quan@hotmail.com">jonny</a>
 * @date 2009 2009-3-27 上午09:38:34
 * @version 1.0.0
 */
public class EntryPointResolverSet implements IEntryPointResolverSet {

	protected transient final Logger logger = LoggerFactory
			.getLogger(getClass());

	private final Set entryPointResolvers = new LinkedHashSet(4);
	private List exceptions = new CopyOnWriteArrayList();

	public Object invoke(Object component, IUuahEventContext context)
			throws Exception {
		try {
			for (Iterator iterator = entryPointResolvers.iterator(); iterator
					.hasNext();) {
				IEntryPointResolver resolver = (IEntryPointResolver) iterator
						.next();
				InvocationResult result = resolver.invoke(component, context);
				if (result.getState() == InvocationResult.STATE_INVOKED_SUCESSFUL) {
					return result.getResult();
				} else {
					if (result.hasError()) {
						exceptions.add(result.getErrorMessage());
					}
				}
			}
			throw new UuahException(CollectionUtils.toString(exceptions, true));
		} finally {
			exceptions.clear();
		}

	}

	public Set getEntryPointResolvers() {
		return entryPointResolvers;
	}

	public void setEntryPointResolvers(Set entryPointResolvers) {
		this.entryPointResolvers.clear();
		this.entryPointResolvers.addAll(entryPointResolvers);
	}

	public void addEntryPointResolver(IEntryPointResolver resolver) {
		synchronized (entryPointResolvers) {
			this.entryPointResolvers.add(resolver);
		}
	}

	public boolean removeEntryPointResolver(IEntryPointResolver resolver) {
		return this.entryPointResolvers.remove(resolver);
	}
}
